# -*- encoding: utf-8 -*-
"""
Copyright (c) 2019 - present AppSeed.us
"""

from django import template
from django.contrib.auth.decorators import login_required
from django.http import HttpResponse, HttpResponseRedirect
from django.template import loader
from django.urls import reverse
from apps.home import models
import random
import os
import json
import zipfile


@login_required(login_url="/login/")
def index(request):
    context = {"segment": "index"}

    html_template = loader.get_template("home/index.html")
    return HttpResponse(html_template.render(context, request))


@login_required(login_url="/login/")
def user_info(request):
    context = {"segment": "user_info"}
    html_template = loader.get_template("home/user_info.html")
    return HttpResponse(html_template.render(context, request))


def history_task(request):
    tasks = models.Task.objects.all()
    print("task num = ", len(tasks))
    print(tasks)
    context = {"segment": "history", "task_num": len(tasks), "tasks": tasks}
    html_template = loader.get_template("home/history.html")
    return HttpResponse(html_template.render(context, request))


def build_graph(edge_code):
    res_data = []
    res_links = []
    node_list = []
    for edge in edge_code:
        node_list.extend(edge)
    node_set = set(node_list)
    border = 50
    node_mapping = {}
    idx = 0
    for node in node_set:
        res_data.append(
            {
                "name": f"G{node}",
                "x": random.randint(border, 1000 - border),
                "y": random.randint(border, 1000 - border),
            }
        )
        node_mapping[node] = idx
        idx += 1
    for node1, node2 in edge_code:
        res_links.append(
            {
                "source": node_mapping[node1],
                "target": node_mapping[node2],
            },
        )
    return {"data": res_data, "links": res_links}


def download_train(request, task_id):
    task = models.Task.objects.get(id=task_id)
    train_data_file = task.train_data_file
    file_path = train_data_file.path
    print("download_by_path", train_data_file)
    with open(file_path, "rb") as f:
        response = HttpResponse(f.read(), content_type="application/octet-stream")
        response["Content-Disposition"] = "inline; filename=" + file_path
        return response


def download_test(request, task_id):
    task = models.Task.objects.get(id=task_id)
    test_data_file = task.gold_data_file
    file_path = test_data_file.path
    print("download_by_path", test_data_file)
    with open(file_path, "rb") as f:
        response = HttpResponse(f.read(), content_type="application/octet-stream")
        response["Content-Disposition"] = "inline; filename=" + file_path
        return response


def download_result(request, task_id):
    task = models.Task.objects.get(id=task_id)
    result_data_file = task.result_data_file
    if result_data_file is None:
        return HttpResponse("No result file")
    file_path = result_data_file.path + "/result.zip"
    if not os.path.exists(file_path):
        os.makedirs(os.path.dirname(file_path), exist_ok=True)
        with zipfile.ZipFile(file_path, "w") as z:
            file1 = os.path.join(result_data_file.path, "training_loss.json")
            file2 = os.path.join(result_data_file.path, "result_info.json")
            z.write(file1, os.path.relpath(file1, result_data_file.path))
            z.write(file2, os.path.relpath(file2, result_data_file.path))

    print("download_by_path", file_path)
    with open(file_path, "rb") as f:
        response = HttpResponse(f.read(), content_type="application/octet-stream")
        response["Content-Disposition"] = "inline; filename=" + file_path
        return response


def display(request, task_id):
    context = {"segment": "display"}
    task = models.Task.objects.get(id=task_id)
    context["task"] = task
    # html_template = loader.get_template("home/display copy 2.html")
    html_template = loader.get_template("home/display.html")
    # result_dir = get_file_path(task.result_data_file)
    training_loss_file = os.path.join(task.result_data_file.path, "training_loss.json")
    result_info_file = os.path.join(task.result_data_file.path, "result_info.json")
    with open(training_loss_file, "r") as f:
        loss_data = json.load(f)
        # loss_data["convergence"]["best"] = loss_data["convergence"]["best"][:5]
        context["loss_data"] = loss_data
    plot_len = len(loss_data["convergence"]["best"])
    context["xaxis"] = list(range(1, plot_len + 1))
    with open(result_info_file, "r") as f:
        result_info = json.load(f)
        context["static_info"] = result_info["train_metrics"]
        graph_data = build_graph(result_info["train_data"]["edges_code"])
        context["graph_data"] = graph_data
    return HttpResponse(html_template.render(context, request))


def task_detail(request, task_id):
    task = models.Task.objects.get(id=task_id)
    context = {"segment": "task_detail", "task": task}
    html_template = loader.get_template("home/task_detail.html")
    return HttpResponse(html_template.render(context, request))


def model_form_create_task(request):
    if request.method == "POST":
        print("POST = ", request.POST)
        print("FILES=", request.FILES)
        context = {"segment": "new_task"}
        new_task = models.Task(
            title=request.POST["title"],
            description=request.POST["description"],
            train_data_file=request.FILES["train_data_file"],
            gold_data_file=request.FILES["gold_data_file"],
        )
        new_task.save()
        new_task.run()
        return HttpResponseRedirect("/info/new_task/success")
    print("but it is not post")

    context = {"segment": "new_task"}

    html_template = loader.get_template("train/new_task.html")
    return HttpResponse(html_template.render(context, request))


@login_required(login_url="/login/")
def pages(request):
    context = {}
    # All resource paths end in .html.
    # Pick out the html file name from the url. And load that template.
    try:

        load_template = request.path.split("/")[-1]

        if load_template == "admin":
            return HttpResponseRedirect(reverse("admin:index"))
        context["segment"] = load_template

        html_template = loader.get_template("home/" + load_template)
        print("html_template_name : ", "home/" + load_template)
        return HttpResponse(html_template.render(context, request))

    except template.TemplateDoesNotExist:

        html_template = loader.get_template("home/page-404.html")
        return HttpResponse(html_template.render(context, request))

    except:
        html_template = loader.get_template("home/page-500.html")
        return HttpResponse(html_template.render(context, request))
